package com.beans.factory;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class DefaultListableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry{

    // 存放 beanDefinition 的 map
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

    // 记录 bean 的注册顺序
    private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

    // 手动注册的 bean
    private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);


    //---------------------------------------------------------------------
    // Implementation of remaining BeanFactory methods
    //---------------------------------------------------------------------

    @Override
    public Object getBean(String name) throws Exception {
        return null;
    }

    @Override
    public <T> T getBean(Class<T> requiredType) throws Exception {
        return getBean(requiredType, (Object[]) null);
    }

    @Override
    public <T> T getBean(String name, Class<T> requiredType) throws Exception {
        return null;
    }

    @Override
    public <T> T getBean(Class<T> requiredType, Object... args) throws Exception {
        // 重点，重点，重点
        NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
        if (namedBean != null) {
            return namedBean.getBeanInstance();
        }
        BeanFactory parent = getParentBeanFactory();
        if (parent != null) {
            return (args != null ? parent.getBean(requiredType, args) : parent.getBean(requiredType));
        }
        throw new NoSuchBeanDefinitionException(requiredType);
    }

    /**
     * 将 beanDefinition 加入到 map 中
     * @param beanName
     * @param beanDefinition
     */
    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        this.beanDefinitionMap.put(beanName, beanDefinition);
        this.beanDefinitionNames.add(beanName);
        this.manualSingletonNames.remove(beanName);
    }

    @Override
    public void removeBeanDefinition(String beanName) throws Exception {

    }

    @Override
    public BeanDefinition getBeanDefinition(String beanName) throws Exception {
        return null;
    }

    @Override
    public boolean containsBeanDefinition(String beanName) {
        return false;
    }

    @Override
    public String[] getBeanDefinitionNames() {
        return new String[0];
    }

    @Override
    public int getBeanDefinitionCount() {
        return 0;
    }

    @Override
    public boolean isBeanNameInUse(String beanName) {
        return false;
    }
}
